/*
   Interrupt hander for the system timer and CS8900a interrupt
*/
#include "config.h"
#include "bulverde.h"
#include "time.h"
#include "serial.h"
#include "smc91x.h"


void sti(void)
{
	asm volatile("stmfd sp!, {r0}");
	asm volatile("mrs r0, cpsr");
	asm volatile("bic r0, r0, #0x80");
	asm volatile("msr cpsr, r0");
	asm volatile("ldmfd sp!, {r0}");
}

void cli(void)
{
	asm volatile("stmfd sp!, {r0}");
	asm volatile("mrs r0, cpsr");
	asm volatile("orr r0, r0, #0x80");
	asm volatile("msr cpsr, r0");
	asm volatile("ldmfd sp!, {r0}");
}

extern void pcf50606_interrupt_entry (void);
void check_onkey();
void c_irq(void)
{

	int interrupt_status;
	cli();
	interrupt_status = (__REG(INTC_BASE_PHYSICAL+ICIP_OFFSET) & __REG(INTC_BASE_PHYSICAL+ICMR_OFFSET)); /* check onlu un-masked interrupts */
//  HEX_LED(interrupt_status);

	if((interrupt_status & IRQ_OST0)!=0){ /* timer interrupt */

		jiffies++;
        check_onkey();
		__REG(OST_BASE_PHYSICAL+OSMR0_OFFSET) = __REG(OST_BASE_PHYSICAL+OSCR0_OFFSET) + (3250000L)/TIMER_TICK_PER_SEC ; /* Trigger interrupts every 10 ms */
		__REG(OST_BASE_PHYSICAL+OSSR_OFFSET) = OSSR_M0; /* clear the inerrupt */

		/* this timer does not count the time required to handle the interrupt,
		 * so actually jiffies take a little longer than 10ms.
		 */
//		return;
//	} else if((interrupt_status & IRQ_GPIO0) != 0) { // FPGA interrupt, We use as a Ethernet IRQ only
//		net_interrupt(&net_dev_lan91c111);

		/* We should some work for clearing FPGA interrupt status bit */
//		__REG(GPIO_BASE_PHYSICAL+GEDR0_OFFSET) = IRQ_GPIO0;
//	} else { /* unknown sources, neglect */

	}

	if((interrupt_status & IRQ_GPIO0)!=0){
		pcf50606_interrupt_entry();
	}


#if 0
	if(( interrupt_status & IRQ_OST_4_11) != 0) {


//		if( *(unsigned int *)(GPIO_BASE_PHYSICAL + GPLR3_OFFSET) & 0x00800000 )
//			*(unsigned int *)(GPIO_BASE_PHYSICAL + GPCR3_OFFSET) = 0x01000000;
//		else
//			*(unsigned int *)(GPIO_BASE_PHYSICAL + GPSR3_OFFSET) = 0x01000000;

		if( __REG(OST_BASE_PHYSICAL+OSSR_OFFSET) & OSSR_M4 ) {

			jiffies_div10++;

//			__REG(OST_BASE_PHYSICAL+OSCR4_OFFSET) = 0; /* reset the counter */
			__REG(OST_BASE_PHYSICAL+OSSR_OFFSET) = OSSR_M4; /* clear the inerrupt */
		}

	}
#endif

	sti();
}

